<template>
  <div>
    <el-button type="primary" link @click="showDialog"> 修改密码 </el-button>

    <el-dialog v-model="dialogVisible" draggable append-to-body title="修改密码" width="500px" :close-on-click-modal="false" @closed="resetForm">
      <el-form ref="formRef" :model="passwordForm" :rules="rules" label-width="80px" class="password-form">
        <el-form-item label="当前密码" prop="oldPassword">
          <el-input v-model="passwordForm.oldPassword" type="password" show-password clearable placeholder="请输入当前密码" :prefix-icon="Lock" />
        </el-form-item>

        <el-form-item label="新密码" prop="newPassword">
          <el-input
            v-model="passwordForm.newPassword"
            type="password"
            show-password
            clearable
            placeholder="请输入新密码"
            :prefix-icon="Key"
            @input="checkPasswordStrength"
          />
          <div class="password-strength" v-if="passwordForm.newPassword">
            <div class="strength-label">密码强度：</div>
            <div class="strength-bars">
              <div
                v-for="(level, index) in 3"
                :key="index"
                class="strength-bar"
                :class="[passwordStrength >= level ? strengthLevelClass : '', { active: passwordStrength >= level }]"
              ></div>
            </div>
            <span class="strength-text" :class="strengthLevelClass">
              {{ strengthLevelText }}
            </span>
          </div>
          <div class="password-tips">
            <el-icon><InfoFilled /></el-icon>
            密码必须包含字母、数字和特殊字符，长度8-20位
          </div>
        </el-form-item>

        <el-form-item label="确认密码" prop="confirmPassword">
          <el-input
            v-model="passwordForm.confirmPassword"
            type="password"
            show-password
            clearable
            placeholder="请再次输入新密码"
            :prefix-icon="Check"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submit" :loading="loading" :disabled="passwordStrength < 2"> 确认修改 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
  import { ref, reactive, computed } from 'vue';
  import { ElMessage } from 'element-plus';
  import { Lock, Key, Check, InfoFilled } from '@element-plus/icons-vue';
  import { RStatus } from '@/common/comstants.js';
  import { useUserApi } from '@/api/user-api.js';
  import { EncryptUtil } from '@/utils/encrypt-util.js';


  const emit = defineEmits(['success']);

  const dialogVisible = ref(false);
  const formRef = ref();
  const loading = ref(false);
  const passwordStrength = ref(0);

  const passwordForm = reactive({
    oldPassword: '',
    newPassword: '',
    confirmPassword: '',
  });

  // 密码强度对应的文本和类名
  const strengthLevelText = computed(() => {
    switch (passwordStrength.value) {
      case 1:
        return '弱';
      case 2:
        return '中';
      case 3:
        return '强';
      default:
        return '弱';
    }
  });

  const strengthLevelClass = computed(() => {
    switch (passwordStrength.value) {
      case 1:
        return 'weak';
      case 2:
        return 'medium';
      case 3:
        return 'strong';
      default:
        return 'weak';
    }
  });

  // 验证新密码
  const validateNewPassword = async (rule, value, callback) => {
    if (value === passwordForm.oldPassword) {
      callback(new Error('新密码不能与当前密码相同'));
    } else {
      if (passwordForm.confirmPassword) {
        formRef.value?.validateField('confirmPassword');
      }
      callback();
    }
  };

  // 验证确认密码
  const validateConfirmPassword = async (rule, value, callback) => {
    if (value !== passwordForm.newPassword) {
      callback(new Error('两次输入的密码不一致'));
    } else {
      callback();
    }
  };

  // 表单验证规则
  const rules = reactive({
    oldPassword: [
      { required: true, message: '请输入当前密码', trigger: 'blur' },
      { min: 6, max: 20, message: '密码长度在 6 到 20 个字符', trigger: 'blur' },
    ],
    newPassword: [
      { required: true, message: '请输入新密码', trigger: 'blur' },
      { min: 8, max: 20, message: '密码长度在 8 到 20 个字符', trigger: 'blur' },
      {
        pattern: /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,20}$/,
        message: '密码必须包含字母、数字和特殊字符',
        trigger: 'blur',
      },
      { validator: validateNewPassword, trigger: 'blur' },
    ],
    confirmPassword: [
      { required: true, message: '请再次输入新密码', trigger: 'blur' },
      { validator: validateConfirmPassword, trigger: 'blur' },
    ],
  });

  // 显示对话框
  const showDialog = () => {
    dialogVisible.value = true;
  };

  // 重置表单
  const resetForm = () => {
    formRef.value?.resetFields();
    passwordStrength.value = 0;
    Object.assign(passwordForm, {
      oldPassword: '',
      newPassword: '',
      confirmPassword: '',
    });
  };

  // 检查密码强度
  const checkPasswordStrength = (password) => {
    if (!password) {
      passwordStrength.value = 0;
      return;
    }

    let strength = 0;
    // 检查长度
    if (password.length >= 8) strength++;
    // 检查是否包含字母和数字
    if (/(?=.*[a-zA-Z])(?=.*\d)/.test(password)) strength++;
    // 检查是否包含特殊字符
    if (/[!@#$%^&*]/.test(password)) strength++;

    passwordStrength.value = strength;
  };

  // 提交表单
  const submit = async () => {
    if (!formRef.value) return;

    await formRef.value.validate(async (valid) => {
      if (valid) {
        loading.value = true;
        try {
          const res = await useUserApi().modifyPassword({
            oldPassword: await EncryptUtil.encrypt(passwordForm.oldPassword),
            newPassword: await EncryptUtil.encrypt(passwordForm.newPassword),
          });

          if (res.status === RStatus.SUCCESS) {
            ElMessage.success('密码修改成功，请重新登录');
            emit('success');
            dialogVisible.value = false;

            // 清除存储并跳转到登录页
            appLocalStorage.clear();
            await ElMessageBox.alert('密码已修改，请重新登录！', '提示', {
              confirmButtonText: '确定',
              type: 'success',
              callback: () => {
                router.push('/login');
              },
            });
          }
        } catch (error) {
          ElMessage.error(error.message || '密码修改失败');
        } finally {
          loading.value = false;
        }
      }
    });
  };
</script>

<style lang="scss" scoped>
  .password-form {
    padding: 20px;

    .password-strength {
      margin-top: 8px;
      display: flex;
      align-items: center;
      gap: 8px;

      .strength-label {
        font-size: 12px;
        color: var(--el-text-color-secondary);
      }

      .strength-bars {
        display: flex;
        gap: 4px;
      }

      .strength-bar {
        width: 40px;
        height: 4px;
        background-color: var(--el-border-color-lighter);
        transition: all 0.3s;

        &.active {
          &.weak {
            background-color: var(--el-color-danger);
          }
          &.medium {
            background-color: var(--el-color-warning);
          }
          &.strong {
            background-color: var(--el-color-success);
          }
        }
      }

      .strength-text {
        font-size: 12px;

        &.weak {
          color: var(--el-color-danger);
        }
        &.medium {
          color: var(--el-color-warning);
        }
        &.strong {
          color: var(--el-color-success);
        }
      }
    }

    .password-tips {
      margin-top: 8px;
      font-size: 12px;
      color: var(--el-text-color-secondary);
      display: flex;
      align-items: center;
      gap: 4px;

      .el-icon {
        color: var(--el-color-info);
      }
    }
  }

  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
    padding-top: 20px;
  }

  .password-tips {
    color: #909399;
    font-size: 12px;
    margin-top: 5px;
  }

  .login-history-card {
    margin-top: 20px;

    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
  }
</style>
@/api/user-api@/utils/encrypt-util